﻿//
// © Algobox Ltd - Benn Eichhorn
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Algobox.Interop.SterlingTrader;
using Algobox.Feeds.Finance.Simulators;
using Algobox.Feeds.Finance.Bats.Adaptors;
using Algobox.Objects.Finance.Assets.Stock;
using System.Collections.Concurrent;
using Algobox.Structure.Finance.Strategies.SpikeArb;
using Algobox.Structure.Finance.Strategies.Terrapin;
using Algobox.Structure.Finance.Strategies.Moss;
using Algobox.Structure.Finance.Strategies.Dastan;
using Algobox.Structure.Finance.Strategies.FractionPrototype;
using System.Xml.Linq;
using System.IO;

namespace ZephyrLite
{
    public class ZephyrLoader
    {
        #region Constructors

        public ZephyrLoader(string username)
        {
            Log.Info("...........");
            Log.Info(":::::::::::");
            Log.Info("Zephyr Lite");
            Log.Info(":::::::::::");
            Log.Info("Loading {0}, {1} ", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name, System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString());
            Log.Info("Kites rise highest against the wind - not with it. Winston Churchill");
            Log.Info("User(" + username + ") logged in");

            Username = username;
        }

        #endregion
//////////////////
        #region Member Variables

        readonly string ZEPHYR_CONFIG_PATH = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "/Algobox/Zephyr/";
        
        /// <summary>
        /// Logger used by this class
        /// </summary>        
        private static readonly NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger();
        
        #endregion
//////////////////
        #region Properties

        public string Username { get; set; }
        public string ConfigFileName { get; private set; }

        public Algobox.Feeds.Finance.MarketData.IMarketFeedAdaptor MarketFeed { get; set; }
        public Algobox.Feeds.Finance.Trading.ITradingFeedAdaptor TradingFeed { get; set; }

        public FractionManagement Fraction { get; private set; }
                
        public bool IsConnected { get; set; }

        /// <summary>
        /// True when SterlingWrapper has connected to Stering Trader
        /// </summary>
        public bool IsSterlingTraderToggleOn { get; private set; }

        public bool IsBatsReplayToggleOn { get; private set; }

        /// <summary>
        /// True when SterlingWrapper has connected to Simulation trading interface
        /// </summary>
        public bool IsSterlingSimulationToggleOn { get; private set; }

        public System.Windows.Data.ListCollectionView FractionOpenView { get { return Algobox.Structure.Finance.Strategies.FractionPrototype.FractionManagement.OpenStrategies.View; } }
        public System.Windows.Data.ListCollectionView FractionDayView { get { return Algobox.Structure.Finance.Strategies.FractionPrototype.FractionManagement.DayStrategies.View; } }
        public System.Windows.Data.ListCollectionView FractionDayMonitorView { get { return Algobox.Structure.Finance.Strategies.FractionPrototype.FractionManagement.DayStrategiesMonitor.View; } }
        public System.Windows.Data.ListCollectionView FractionTriggerView { get { return Algobox.Structure.Finance.Strategies.FractionPrototype.FractionManagement.Triggers.View; } }

        #endregion
//////////////////
        #region Functions
        
        /// <summary>
        /// Loads the SterlingWrapper and return true when connected
        /// </summary>
        /// <returns></returns>
        public bool Connect_SterlingSimulation()
        {
            lock (this)
            {
                if (!IsSterlingSimulationToggleOn)
                {
                    Log.Info("Connecting Sterling");
                    try
                    {
                        // Sterling Trader price feed
                        Algobox.Apps.Finance.SterlingTrader.QuoteAdaptor marketFeed = new Algobox.Apps.Finance.SterlingTrader.QuoteAdaptor("SterlingTrader");
                        SterlingWrapper.QuoteManager = (QuoteManagement)marketFeed;

                        TradingSimulator tradingFeed = new TradingSimulator();
                        
                        if (!marketFeed.Start())
                            return false;

                        if (!tradingFeed.Start())
                            return false;

                        MarketFeed = marketFeed;
                        TradingFeed = tradingFeed;

                        ConcurrentDictionary<string, StockSecurity> stocks = new ConcurrentDictionary<string, StockSecurity>();
                        Algobox.Data.Finance.SterlingTestData dataContract = new Algobox.Data.Finance.SterlingTestData(stocks);

                        Fraction = new FractionManagement(marketFeed, dataContract);

                        ConfigFileName = ZEPHYR_CONFIG_PATH + "ZepherLite.SterlingSimulation.xml";
                        if (System.IO.File.Exists(ConfigFileName))
                        {
                            XElement xml = XElement.Load(ConfigFileName, LoadOptions.None);
                            Fraction.LoadConfig(xml);
                        }

                        IsSterlingSimulationToggleOn = true;
                        return true;
                    }
                    catch
                    {
                        IsSterlingSimulationToggleOn = false;
                    }
                }
            }
            return false;
        }

        internal bool Connect_BatsReplay()
        {
            lock (this)
            {
                if (!IsBatsReplayToggleOn)
                {
                    Log.Info("Connecting Bats Replay");
                    PitchFileMarketFeedAdaptor marketFeed = new PitchFileMarketFeedAdaptor();
                    TradingSimulator tradingFeed = new TradingSimulator();

                    if (!marketFeed.Start())
                        return false;

                    if (!tradingFeed.Start())
                        return false;

                    MarketFeed = marketFeed;
                    TradingFeed = tradingFeed;

                    ConcurrentDictionary<string, StockSecurity> stocks = new ConcurrentDictionary<string, StockSecurity>();

                    Algobox.Data.Finance.BatsReplayTestData dataSource = new Algobox.Data.Finance.BatsReplayTestData(stocks);

                    Fraction = new FractionManagement(marketFeed, dataSource);

                    ConfigFileName = ZEPHYR_CONFIG_PATH + "ZepherLite.BatsReplay.xml";
                    if (System.IO.File.Exists(ConfigFileName))
                    {
                        XElement xml = XElement.Load(ConfigFileName, LoadOptions.None);
                        Fraction.LoadConfig(xml);
                    }

                    IsBatsReplayToggleOn = true;
                }
            }
            return true;
        }
        
        internal void LoadFile_BatsReplay(string filename)
        {
            if (IsBatsReplayToggleOn && Fraction != null)
            {
                System.IO.FileInfo fi = new System.IO.FileInfo(filename);
                ((Algobox.Feeds.Finance.Bats.Adaptors.PitchFileMarketFeedAdaptor)Fraction.MarketFeed).ProcessFile(fi);
            }
        }

        internal void Exit()
        {            
            Log.Info("Shutting down Sterling API");
            try
            {
                if (MarketFeed != null)
                    MarketFeed.Stop();

                if (TradingFeed != null)
                    TradingFeed.Stop();

            }
            catch
            { }
            

            
            Log.Info("{0} Terminated", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
            Log.Info(":::::::");
            Log.Info(".......");
        }
        
        internal void SaveConfig()
        {
            XElement xml = Fraction.SaveConfig();
            Directory.CreateDirectory(Path.GetDirectoryName(ConfigFileName));
            xml.Save(ConfigFileName, SaveOptions.None);
        }

        #endregion
//////////////////
        #region Enums



        #endregion



        internal void FractionOpenRemove(FractionComponentOpen strategy)
        {
            Fraction.Remove(strategy);
        }

        internal void FractionDayRemove(FractionComponentDay strategy)
        {
            Fraction.Remove(strategy);
        }
    }
}
